#include <iostream>
#include <fstream>
#include <memory>
#include <NetworkSnapshotTextDumper.h>
#include <NetworkSnapshotGraphVizDumper.h>
#include <ViewerException.h>
#include "NetworkSnapshotProviderFile.h"
#include "test.h"

/* Validates viewer snapshot model for xml parsing correctness */
int main(int argc, char* argv[]) {
  try {
    std::auto_ptr<INetworkSnapshotProvider> snapshotProvider(
      new NetworkSnapshotProviderFile("parsing.xml"));
    std::auto_ptr<INetworkSnapshotDumper> snapshotDumperText(
      new NetworkSnapshotTextDumper());
    std::auto_ptr<NetworkSnapshot> snapshot(
      snapshotProvider->getSnapshot(std::cerr));
    /* Test logic */
    Networks::const_iterator netIt, netEnd;
    netIt = snapshot->getNetworks().begin();
    netEnd = snapshot->getNetworks().end();

    for(; netIt != netEnd; ++netIt) {
      assertTrue(netIt->getId() == "SPbAU");

      SubNetMap::const_iterator subNetIt, subNetItEnd;
      subNetIt = netIt->getSubNetworks().begin();
      subNetItEnd = netIt->getSubNetworks().end();

      NetRouters::const_iterator routeIt, routeEnd;
      routeIt = netIt->getRouters().begin();
      routeEnd = netIt->getRouters().end();

      for(; subNetIt != subNetItEnd; ++subNetIt) {
        assertTrue(subNetIt->second.getId() == 
            SubNet::strToId("10.0.0.0"));

        NetNodes::const_iterator nodeIt, nodeItEnd;
        nodeIt  = subNetIt->second.getNodes().begin();
        nodeItEnd = subNetIt->second.getNodes().end();
        
        for(; nodeIt != nodeItEnd; ++nodeIt) {
          assertTrue(nodeIt->getAddress() == 
              NetAddress(NA_IPV4, inet_addr("10.0.0.200")));
        }
      }

      for(; routeIt != routeEnd; ++routeIt) {
        assertTrue(routeIt->getDescription() == "Cisco IOS");

        NetInterfaces::const_iterator interfIt, interfItEnd;
        interfIt = routeIt->getInterfaces().begin();
        interfItEnd = routeIt->getInterfaces().end();

        for(; interfIt != interfItEnd; ++interfIt) {
          assertTrue(interfIt->getAddress()  == 
              NetAddress(NA_IPV4, inet_addr("10.0.0.200")));
          assertTrue(interfIt->getMask()     == 
              inet_addr("255.255.255.0"));
          assertTrue(interfIt->getSubNetId() == 
            SubNet::strToId("10.0.0.0"));
          assertTrue(interfIt->getName()     == "10.0.0.200");
          assertTrue(interfIt->getInBytes()  == 222);
          assertTrue(interfIt->getOutBytes() == 111);
        }
      }
    }
  } catch(ViewerException& ex) {
    std::cerr << "Error occured: " << std::endl
              << ex.what()         << std::endl;
  }
  std::cout << "Success!" << std::endl;
  return 0;
}
